package com.fast.develop.dm.core.util;

import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 项 目 名：GS-Titan-Framework 源文件名：com.geekstorm.titan.framework.common.utils.TypeUtil
 * 文件版本：1.0.0 创建人： 莫寅 创建日期：2020-05-23 21:32 修改作者：莫寅 修改日期：2020-05-23 21:32 文件描述： By：2020
 * © CompanyName , Inc. All Rights Reserved.
 */
public class TypeUtil {

	public static Class getOneClass(Class tClass) {
		Type type = tClass.getGenericSuperclass();// 拿到带类型参数的泛型父类
		// if(type instanceof
		// ParameterizedType){//这个Type对象根据泛型声明，就有可能是4中接口之一，如果它是BaseDao<User>这种形式
		// ParameterizedType parameterizedType = (ParameterizedType) type;
		// Type[] actualTypeArguments =
		// parameterizedType.getActualTypeArguments();//获取泛型的类型参数数组
		// if(actualTypeArguments != null && actualTypeArguments.length > 0){
		// if(actualTypeArguments[0] instanceof Class){//类型参数也有可能不是Class类型
		// return (Class) actualTypeArguments[0];
		// }else{
		// TypeVariable t = (TypeVariable)actualTypeArguments[0];
		// Type[] _types = t.getBounds();
		//
		// return ((ParameterizedTypeImpl)_types[0]).getRawType();
		//
		// }
		// }
		// }
		Class[] classes = getClassesByType(type);

		return classes != null && classes.length > 0 ? classes[0] : null;
	}

	public static Class[] getClasses(Class tClass) {
		Type type = tClass.getGenericSuperclass();// 拿到带类型参数的泛型父类

		return getClassesByType(type);
	}

	/**
	 * 获取类的参数类型
	 * @param tClass
	 * @return
	 */
	public static Class[] getClassesByTypeParameters(Class tClass) {
		List<Class> classes = new ArrayList<>();
		for (TypeVariable typeVariable : tClass.getTypeParameters()) {
			for (Type _types : typeVariable.getBounds()) {
				if (_types instanceof Class) {
					classes.add((Class) _types);
				}
				else if (_types instanceof ParameterizedTypeImpl) {
					classes.add(((ParameterizedTypeImpl) _types).getRawType());
				}
			}
		}
		return classes.toArray(new Class[classes.size()]);
	}

	public static Class[] getClassesByType(Type type) {
		if (type instanceof ParameterizedType) {// 这个Type对象根据泛型声明，就有可能是4中接口之一，如果它是BaseDao<User>这种形式
			ParameterizedType parameterizedType = (ParameterizedType) type;
			Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();// 获取泛型的类型参数数组
			if (actualTypeArguments != null && actualTypeArguments.length > 0) {

				Class[] classes = new Class[actualTypeArguments.length];
				for (int i = 0; i < actualTypeArguments.length; i++) {
					Type _type = actualTypeArguments[i];

					if (_type instanceof Class) {// 类型参数也有可能不是Class类型
						classes[i] = (Class) _type;
					}
					else if (_type instanceof ParameterizedType) {
						classes[i] = ((ParameterizedTypeImpl) ((ParameterizedType) _type)).getRawType();
					}
					else {
						TypeVariable t = (TypeVariable) _type;
						Type[] _types = t.getBounds();
						if (_types[0] instanceof Class) {
							classes[i] = (Class) _types[0];
						}
						else if (_types[0] instanceof ParameterizedTypeImpl) {
							classes[i] = ((ParameterizedTypeImpl) _types[0]).getRawType();
						}
					}
				}
				return classes;
			}
		}
		return new Class[0];
	}

	public static Class[] getClassesInterfaces(Class tClass) {
		List<Class> classList = new ArrayList<>();
		Arrays.stream(tClass.getGenericInterfaces()).forEach(type -> {
			classList.addAll(Arrays.asList(getClassesByType(type)));
		});
		return classList.toArray(new Class[0]);
	}

}
